home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / sozo2 / scsrc20.lzh / JAS.LZH / SYM.C < prev   
Encoding:
C/C++ Source or Header  |  1991-02-22  |  6.2 KB  |  346 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. #define SYMSZ 64
  17. #define NHASH 373
  18. #define SYMLOOP(x,y) for(x=0;x<SYMSZ&&full[x]>0;x++) for(y=0;y<full[x];y++)
  19.  
  20. /* ordering definitions */
  21. #define O_SUPPRESS    000
  22. #define O_STATIC    001
  23. #define O_GLOBAL    002
  24. #define O_UNDEF        004
  25.  
  26. long nsyms = 0;
  27. SYM *table[NHASH];
  28.  
  29. SYM *sym_tab[SYMSZ];
  30. short full[SYMSZ];
  31. int level = 0;
  32. extern int Lflag;
  33. extern int flag8;
  34.  
  35. #ifdef UNIXHOST
  36. char *fixsym();
  37. #define FSYMSZ    14
  38. #endif
  39.  
  40. /*
  41.  * this table is used to store long names
  42.  */
  43.  
  44. char **flexnames = (char **) NULL; 
  45. int *flexused = (int *) 0;
  46. int flexsize = 0;
  47.  
  48. setname( p, name )
  49.     SYM *p;
  50.     char *name;
  51. {
  52.     int i, len = strlen( name );
  53.  
  54.     if ( flag8 || len <= 8 ) {
  55.         strncpy( p->name.here, name, 8 );
  56.         return;
  57.     }
  58.     if ( flexsize == 0 ) {
  59.         flexused = ALLO(int);
  60.         flexused[0] = 0;
  61.         flexnames = ALLO(char *);
  62.         flexnames[0] = ALLOC(1024,char);
  63.         flexsize = 1;
  64.     }
  65.     if ( flexused[flexsize-1] + len + 1 > 1024 ) {
  66.         flexsize++;
  67.         flexused = REALLO(flexused,flexsize,int);
  68.         flexused[flexsize-1] = 0;
  69.         flexnames = REALLO(flexnames,flexsize,char *);
  70.         flexnames[flexsize-1] = ALLOC(1024,char);
  71.     }
  72.     i = flexsize-1;
  73.     p->name.stix[0] = 0;
  74.     p->name.stix[1] = 1024 * i + flexused[i];
  75.     strcpy( &flexnames[i][flexused[i]], name );
  76.     flexused[i] += len + 1;
  77. }
  78.  
  79. cpyname( dst, p )
  80.     char dst[8];
  81.     SYM *p;
  82. {
  83.     int i, j;
  84.  
  85.     if ( ! p->name.stix[0] ) {
  86.         i = p->name.stix[1] / 1024;
  87.         j = p->name.stix[1] % 1024;
  88.         strncpy( dst, &flexnames[i][j], 8 );
  89.         return;
  90.     }
  91.     for ( i = 0; p->name.here[i] && i < 8; i++ )
  92.         dst[i] = p->name.here[i];
  93.     for ( ; i < 8; i++ )
  94.         dst[i] = (char) 0;
  95. }
  96.  
  97. cmpname( p, name )
  98.     SYM *p;
  99.     char *name;
  100. {
  101.     if (flag8)
  102.         return strncmp(name, p->name.here, 8);
  103.  
  104.     if ( ! p->name.stix[0] ) {
  105.         int i, j;
  106.  
  107.         i = p->name.stix[1] / 1024;
  108.         j = p->name.stix[1] % 1024;
  109.  
  110.         return strcmp( name, &flexnames[i][j] );
  111.     }
  112.     if (strlen(name) > 8)
  113.         return 1;
  114.     return strncmp( name, p->name.here, 8 );
  115. }
  116.  
  117. SYM *
  118. newsym( )
  119. {
  120.     register SYM *p;
  121.  
  122.     if ( full[level] >= SYMSZ ) {
  123.         if ( ++level >= SYMSZ )
  124.             error( 0, "symbol table full" );
  125.     }
  126.     if (! sym_tab[level] ) {
  127.         sym_tab[level] = ALLOC(SYMSZ,SYM);
  128.         full[level] = 0;
  129.     }
  130.     p = &sym_tab[level][full[level]++];
  131.     p->flags = 0;
  132.     return p;
  133. }
  134.  
  135. SYM *
  136. lookup(name)
  137.     register char *name;
  138. {
  139.     register int h;
  140.     register SYM *p;
  141.  
  142.     h = hash( name );
  143.     if ( p = table[h] ) {
  144.         for ( ; p != (SYM *) NULL; p = p->next) {
  145.             if (! cmpname( p, name ) ) {
  146.                 return p;
  147.             }
  148.         }
  149.         p = newsym();
  150.         setname( p, name );
  151.         p->next = table[h];
  152.         table[h] = p;
  153.         return p;
  154.     }
  155.     p = table[h] = newsym();
  156.     setname( p, name );
  157.     return p;
  158. }
  159.  
  160. symwalk(acc,fun)
  161.     register int acc;
  162.     register int (*fun)();
  163. {
  164.     register int lvl, i;
  165.     register SYM *p;
  166.  
  167.     SYMLOOP(lvl,i) {
  168.         p = &sym_tab[lvl][i];
  169.  
  170.         if (acc & p->access)
  171.             (*fun)(p);
  172.         }
  173. }
  174.  
  175. putsym(p)
  176.     register SYM *p;
  177. {
  178.     struct {
  179.         char name[8];
  180.         unsigned short flags;
  181.         long value;
  182.     } s;
  183.     register int i;
  184.     register char *cp;
  185.     int j, k;
  186.  
  187.     cpyname( s.name, p );
  188.  
  189.     s.value = p->value;
  190.  
  191.     s.flags = p->flags;
  192.     if ( s.flags == DEFINED || s.flags == (DEFINED|GLOBAL) )
  193.         s.flags |= EXTERN;
  194.  
  195. #ifndef UNIXHOST
  196.     output( (char *) &s, sizeof s, 1 );
  197. #else
  198.     output( fixsym(&s), FSYMSZ, 1 );
  199. #endif
  200.  
  201.     if (flag8 || p->name.stix[0])
  202.         return;
  203.  
  204.     i = p->name.stix[1] / 1024;
  205.     j = p->name.stix[1] % 1024;
  206.     cp = &flexnames[i][j];
  207.  
  208.     j = strlen(cp);
  209.     i = 8;
  210.     while (j > i) {
  211.         strncpy(s.name, &cp[i], 8);
  212.         for (k=j-i; k<8; k++)
  213.             s.name[k] = 0;
  214.         s.flags = NAMEX;
  215.         s.value = NAMEV;
  216. #ifndef UNIXHOST
  217.         output( (char *) &s, sizeof s, 1 );
  218. #else
  219.         output( fixsym(&s), FSYMSZ, 1 );
  220. #endif
  221.         i += 8;
  222.     }
  223. }
  224.  
  225. flexsym()
  226. {
  227.     struct {
  228.         char name[8];
  229.         unsigned short flags;
  230.         long value;
  231.     } s;
  232.  
  233.     strcpy(s.name, "SozobonX");
  234.     s.value = NAMEV;
  235.     s.flags = NAMEX;
  236.  
  237. #ifndef UNIXHOST
  238.     output( (char *) &s, sizeof s, 1 );
  239. #else
  240.     output( fixsym(&s), FSYMSZ, 1 );
  241. #endif
  242. }
  243.  
  244. dumpsym()
  245. {
  246.     if (!flag8)
  247.         flexsym();
  248.     /*
  249.      * don't generate static symbols
  250.      */
  251.     if ( Lflag > 0 )
  252.         symwalk( O_STATIC, putsym );
  253.     symwalk( O_GLOBAL, putsym );
  254.     symwalk( O_UNDEF, putsym );
  255. }
  256.  
  257. setindex( p )
  258.     SYM *p;
  259. {
  260.     int i, j, n;
  261.     char *cp;
  262.  
  263.     if (flag8 || p->name.stix[0])
  264.         n = 1;
  265.     else {
  266.         i = p->name.stix[1] / 1024;
  267.         j = p->name.stix[1] % 1024;
  268.         cp = &flexnames[i][j];
  269.         n = (strlen(cp) + 7) / 8;
  270.     }
  271.  
  272.     p->index = nsyms;
  273.     nsyms += n;
  274. }
  275.  
  276. symindex()
  277. {
  278.     register int lvl, i;
  279.     register SYM *p;
  280.  
  281.     SYMLOOP(lvl,i) {
  282.         p = &sym_tab[lvl][i];
  283.         p->access = 0;
  284.         if ( (p->flags & DEFINED) == 0 ) {
  285.             p->access = O_SUPPRESS;
  286.         } else if ( (p->flags & (SEGMT|EQUATED)) &&
  287.                         ! (p->flags & GLOBAL) ) {
  288.             /*
  289.              * if a static symbol starts with an L,
  290.              * then it is truely invisible
  291.              */
  292.             char name[8];
  293.  
  294.             cpyname( name, p );
  295.  
  296.             if ( p->flags & SEGMT && Lflag <= 1 && name[0] == 'L' )
  297.                 p->access = O_SUPPRESS;
  298.             else
  299.                 p->access = O_STATIC;
  300.         } else if ( p->flags & (SEGMT|EQUATED) ) {
  301.             p->access = O_GLOBAL;
  302.         } else { /*  (p->flags & SEGMT) == UNK */
  303.             p->access = O_UNDEF;
  304.         }
  305.     }
  306.     if (flag8)
  307.         nsyms = 0;
  308.     else
  309.         nsyms = 1;
  310.     /*
  311.      * don't generate static symbols
  312.      */
  313.     if ( Lflag > 0 )
  314.         symwalk( O_STATIC, setindex );
  315.     symwalk( O_GLOBAL, setindex );
  316.     symwalk( O_UNDEF, setindex );
  317. }
  318.  
  319. int
  320. hash(name)
  321.     register char *name;
  322. {
  323.     register int val;
  324.     register int i;
  325.  
  326.     for (val = 0, i=0; i < 6 && *name; i++,name++)
  327.         val += (int) *name;
  328.     return val % NHASH;
  329. }
  330.  
  331. fixsymval( addr, incr, segmt )
  332.     register long addr, incr;
  333.     unsigned short segmt;
  334. {
  335.     register int lvl, i;
  336.     register SYM *p;
  337.  
  338.     SYMLOOP(lvl,i) {
  339.         p = &sym_tab[lvl][i];
  340.  
  341.         if ( ( p->flags & SEGMT ) == segmt && p->value >= addr )
  342.             p->value += incr;
  343.     }
  344. }
  345.  
  346.